﻿
namespace n_PianoPanel
{
using System;
using System.Drawing;
using System.Windows.Forms;
using n_MusicFunction;
using c_MIDI;
using n_OS;

//*****************************************************
//钢琴键盘容器类
public class PianoPanel : Panel
{
	public bool isMoveMode;
	public int Volume;
	
	Label[] Key;
	
	int Last;
	
	bool isDown;
	int LastX;
	
	const int StartSoundIndex = 24;
	
	/*
	const int WhiteKeyWidth = 14;
	const int WhiteKeyHeight = 81;
	const int BlackKeyWidth = 8;
	const int BlackKeyHeight = 53;
	const int X_Offset = 14;
	*/
	
	const int WhiteKeyWidth = 28;
	const int WhiteKeyHeight = 100;
	const int BlackKeyWidth = 16;
	const int BlackKeyHeight = 58;
	const int X_Offset = 28;
	
	//6组键
	//SIZE: 618, 119
	//const int KeyNumber = 73;
	
	//7组键+1
	//SIZE: 716, 119
	const int KeyNumber = 84;
	
	Label ll;
	//7组键
	//SIZE: 716, 119
	//const int KeyNumber = 84;
	
	
	//鼠标按键事件委托
	public delegate void MyKeyPressEventHandler( int KeyIndex );
	//按下琴键触发的事件
	public event MyKeyPressEventHandler MyKeyPress;
	
	//构造函数
	public PianoPanel()
	{
		this.BorderStyle = BorderStyle.None;
		this.BackColor = Color.White;
		
		//this.Dock = DockStyle.Fill;
		
		this.Width = WhiteKeyWidth * 49 + 10;
		this.Height = WhiteKeyHeight;
		
		//this.BackgroundImage = new Bitmap( OS.SystemRoot + "resource" + OS.PATH_S + "MusicBox" + OS.PATH_S + "电子琴7+1.gif" );
		//this.BackgroundImageLayout = ImageLayout.Stretch;
		
		Volume = 127;
		isMoveMode = false;
		
		Last = -1;
		
		isDown = false;
		
		ll = new Label();
		ll.Text = "← 左键左右拖动可调节键盘位置 →";
		ll.ForeColor = Color.Black;
		ll.TextAlign = ContentAlignment.MiddleCenter;
		ll.Visible = false;
		ll.Font = new Font( "微软雅黑", 12 );;
		ll.Height = 40;
		ll.Width = this.Width;
		ll.Location = new Point( 0, 0 );
		ll.BackColor = Color.NavajoWhite;
		ll.MouseEnter += new EventHandler( ll_MouseEnter );
		this.Controls.Add( ll );
		
		InitKetboard();
	}
	
	//键盘初始化
	void InitKetboard()
	{
		int Y = 0;
		int X_Start = 7;
		
		int BaseIndex = 0;
		Key = new Label[ KeyNumber ];
		for( int i = 0; i < Key.Length; ++i ) {
			Key[ i ] = new Label();
			Key[ i ].Name = ( i ).ToString();
			Key[ i ].TextAlign = ContentAlignment.BottomCenter;
			Key[ i ].ImageAlign = ContentAlignment.BottomCenter;
			
			Key[ i ].MouseDown += new MouseEventHandler( MDown );
			Key[ i ].MouseUp += new MouseEventHandler( MUp );
			Key[ i ].MouseEnter += new EventHandler( MEnter );
			Key[ i ].MouseLeave += new EventHandler( MLeave );
			Key[ i ].MouseMove += new MouseEventHandler( MMove );
			Key[ i ].BorderStyle = BorderStyle.FixedSingle;
			
			if( MusicFunction.isWhiteKey( i ) ) {
				Key[ i ].Width = WhiteKeyWidth;
				Key[ i ].Height = WhiteKeyHeight;
				Key[ i ].Location = new Point( X_Start - 1, Y );
				Key[ i ].BackColor = Color.White;
				X_Start += X_Offset;
			}
			else {
				Key[ i ].Width = BlackKeyWidth;
				Key[ i ].Height = BlackKeyHeight;
				Key[ i ].Location = new Point( X_Start - Key[ i ].Width/2, Y );
				Key[ i ].BackColor = Color.Black;
				this.Controls.Add( Key[ i ] );
			}
			
			if( MusicFunction.isWhiteKey( i ) ) {
				
				string text = ( BaseIndex % 7 + 1 ).ToString();
				++BaseIndex;
				
				if( i < 12 ) {
					Key[ i ].ForeColor = Color.FromArgb( 0, 0, 100 );
					text = "lll" + text;
				}
				else if( i < 24 ) {
					Key[ i ].ForeColor = Color.FromArgb( 0, 0, 100 );
					text = "ll" + text;
				}
				else if( i < 36 ) {
					Key[ i ].ForeColor = Color.Blue;
					text = "l" + text;
				}
				else if( i < 48 ) {
					Key[ i ].ForeColor = Color.Black;
					//...
				}
				else if( i < 60 ) {
					Key[ i ].ForeColor = Color.Red;
					text = "h" + text;
				}
				else if( i < 72 ) {
					Key[ i ].ForeColor = Color.Red;
					text = "hh" + text;
				}
				else {
					Key[ i ].ForeColor = Color.FromArgb( 100, 0, 0 );
					text = "hhh" + text;
				}
				Key[ i ].Image = new Bitmap( AppDomain.CurrentDomain.BaseDirectory + @"Resource\MusicBox\img\" + text + ".png" );
			}
		}
		for( int i = 0; i < Key.Length; ++i ) {
			if( MusicFunction.isWhiteKey( i ) ) {
				this.Controls.Add( Key[ i ] );
			}
		}
	}
	
	void ll_MouseEnter( object sender, EventArgs e )
	{
		ll.Visible = false;
	}
	
	//鼠标按键事件
	void MDown( object sender, MouseEventArgs e )
	{
		ll.Visible = false;
		
		int Index = int.Parse( ( (Label)sender ).Name );
		Index += StartSoundIndex;
		
		if( e.Button == MouseButtons.Left ) {
			if( Last != -1 ) {
				Music.CloseSound( 0, Last );
			}
			Music.PlaySound( 0, Index , Volume );
			Last = Index;
			if( MusicFunction.isWhiteKey( Index ) ) {
				((Label)sender).BackColor = Color.Orange;
			}
			else {
				((Label)sender).BackColor = Color.SlateBlue;
			}
			if( MyKeyPress != null ) {
				MyKeyPress( Index );
			}
			
			isDown = true;
			LastX = e.X;
		}
		else if( e.Button == MouseButtons.Right ) {
			
		}
	}
	
	//鼠标抬键事件
	void MUp( object sender, MouseEventArgs e )
	{
		if( e.Button == MouseButtons.Left ) {
			int Index = int.Parse( ( (Label)sender ).Name );
			
			//未处理声音的关闭
			//if( !TimbreBox1.isShort ) {
			//	Music.CloseSound( 0, Index + MusicFunction.StartSoundIndex );
			//}
			if( MusicFunction.isWhiteKey( Index ) ) {
				( (Label)sender ).BackColor = Color.White;
			}
			else {
				( (Label)sender ).BackColor = Color.Black;
			}
			
			isDown = false;
		}
		else if( e.Button == MouseButtons.Right ) {
			
		}
	}
	
	//鼠标进入事件
	void MEnter( object sender, EventArgs e )
	{
		int Index = int.Parse( ( (Label)sender ).Name );
		Index += StartSoundIndex;
		
		if( isMoveMode ) {
			if( Last != -1 ) {
				Music.CloseSound( 0, Last );
			}
			Music.PlaySound( 0, Index , Volume );
			Last = Index;
		}
		if( MusicFunction.isWhiteKey( Index ) ) {
			( (Label)sender ).BackColor = Color.LightSlateGray;
		}
		else {
			( (Label)sender ).BackColor = Color.DarkSlateGray;
		}
	}
	
	//鼠标退出事件
	void MLeave( object sender, EventArgs e )
	{
		int Index = int.Parse( ( (Label)sender ).Name );
		//Music.CloseSound( 0, Index + MusicBox.StartSoundIndex );
		if( MusicFunction.isWhiteKey( Index ) ) {
			( (Label)sender ).BackColor = Color.White;
		}
		else {
			( (Label)sender ).BackColor = Color.Black;
		}
	}
	
	//鼠标移动事件
	void MMove( object sender, MouseEventArgs e )
	{
		if( isDown ) {
			Location = new Point( Location.X + (e.X - LastX), Location.Y );
		}
		
		//LastX = e.X;
	}
}
}



